namespace Todos.Application.TodoLists.Commands;

[AuthConfig(typeof(TodoList), ResourceAccessType.RoleLimit, "Create")]
public class CreateTodoListCommand : IRequest<ApiResult>, ICommand
{
    public TodoListInDto[] Dtos { get; set; } = [];
}

public class CreateTodoListCommandHandler(IServiceProvider provider) : IRequestHandler<CreateTodoListCommand, ApiResult>
{
    public async Task<ApiResult> Handle(CreateTodoListCommand request, CancellationToken cancellationToken)
    {
        var repository = provider.GetRepository<TodoList>();
        var entities = request.Dtos.Select(dto => dto.MapTo<TodoList>()).ToArray();
        await repository.InsertAsync(entities, cancellationToken);
        return new ApiResult(ApiResultType.Success, $"待办列表 {entities.ExpandAndToString(m => m.Name)} 创建成功");
    }
}

public class CreateTodoListCommandValidator : AbstractValidator<CreateTodoListCommand>
{
    public CreateTodoListCommandValidator(IRepository<TodoList> repository)
    {
        RuleFor(v => v.Dtos).NotEmpty().WithMessage("请至少创建一个待办列表")
        .Must(dtos =>
        {
            var names = dtos.Select(dto => dto.Name).ToList();
            return names.Count == names.Distinct().Count();
        }).WithMessage("批量创建的待办列表中存在重复的名称");

        RuleForEach(m => m.Dtos).ChildRules(dto =>
        {
            dto.RuleFor(m => m.Name).NotEmpty().WithMessage("待办列表名称不能为空")
            .MustAsync(async (name, cancellation) =>
            {
                var spec = new TodoListByNameSpec(name);
                var exists = await repository.AnyAsync(spec, cancellation);
                return !exists;
            }).WithMessage(m => $"待办列表名称{m.Name}已存在");
        });
    }
}
